using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ToolTipListBoxNameSpace
{
	public class ToolTipListBox : ListBox
	{
		public struct SIZE
		{
			public int cx;

			public int cy;
		}

		private const int LB_ADDSTRING = 384;

		private const int LB_INSERTSTRING = 385;

		private const int LB_DELETESTRING = 386;

		private const int LB_RESETCONTENT = 388;

		private int LastIndex = -1;

		private ToolTip tp = new ToolTip();

		public event EventHandler ItemsChanged = delegate
		{
		};

		[DllImport("gdi32.dll")]
		public static extern int GetTextExtentPoint32(IntPtr hdc, string str, int len, ref SIZE size);

		[DllImport("user32.dll")]
		public static extern IntPtr GetDC(IntPtr hWnd);

		[DllImport("user32.dll")]
		public static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);

		public ToolTipListBox()
		{
			tp.InitialDelay = 500;
			tp.ReshowDelay = 500;
			tp.AutoPopDelay = 3000;
			tp.Active = true;
		}

		protected override void WndProc(ref Message m)
		{
			if ((m.Msg == 384 || m.Msg == 385 || m.Msg == 386 || m.Msg == 388) && this.ItemsChanged != null)
			{
				this.ItemsChanged(this, EventArgs.Empty);
			}
			base.WndProc(ref m);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			int num = IndexFromPoint(e.X, e.Y);
			if (num == -1)
			{
				return;
			}
			string text = ((SourceList)base.Items[num]).SValue.ToString();
			if (LastIndex != num || text != tp.GetToolTip(this))
			{
				IntPtr dC = GetDC(base.Handle);
				SIZE size = default(SIZE);
				size.cx = 0;
				size.cy = 0;
				GetTextExtentPoint32(dC, text, text.Length, ref size);
				ReleaseDC(base.Handle, dC);
				if (base.Width < size.cx)
				{
					tp.SetToolTip(this, text);
				}
				else
				{
					tp.SetToolTip(this, text);
				}
				LastIndex = num;
			}
		}

		public void RefreshListBox()
		{
			LastIndex = -1;
		}
	}
}
